package {
	import flash.utils.setTimeout;
	import flash.display.MovieClip;

	import tools.utils.ArrayUtil;
	import tools.utils.Rnd;

	import com.greensock.easing.Bounce;
	// import com.junkbyte.console.Cc;
	import com.greensock.TweenLite;
	import com.greensock.easing.Cubic;

	import tools.events.InteractiveEvent;

	/**
	 * 电梯
	 * @author ase7en
	 */
	public class LiftBox extends MovieClip {
		public static const MAX_FLOOR : int = 6;
		public static const MIN_FLOOR : int = 1;
		public static const MAX_PEOPLE : int = 10;
		public static const FLOOR_H : Number = 110;
		private var _currentFloor : int = 1;
		private var _personArr : Array = [];
		// 电梯Y位置
		private var _point_Y : Array = [629, 519, 403, 292, 174, 58];
		// 电梯空位
		private var _seatIndex : Array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
		// 电梯移动方向
		private var _moveType : String = "up";
		// 目标层
		private var _endFloor : int;
		// 是否有人进入
		private var _isGoIn : Boolean;
		// 是否有人离开
		private var _isGoOut : Boolean;
		// 电梯模式
		private var _mode : String;
		// 电梯编号
		private var _index : int;
		private var _isStop : Boolean;

		public function LiftBox() {
			_personArr = PersonDataManager.personArr;
		}

		/**
		 * 移动电梯
		 */
		public function move(type : String) : void {
			mode = "move";
			_isStop = false;
			if (type != _moveType) {
				_moveType = type;
			}
			dispatchEvent(new InteractiveEvent(LiftEvent.CHANGE_MOVE_TYPE, _moveType));
			if (type == "up" && _currentFloor < MAX_FLOOR) {
				_currentFloor++;
				TweenLite.to(this, Config.speedLift, {y:_point_Y[_currentFloor - 1], ease:Cubic.easeInOut, onComplete:onMoveCom, onCompleteParams:[_currentFloor]});
			} else if (type == "down" && _currentFloor > MIN_FLOOR) {
				_currentFloor--;
				TweenLite.to(this, Config.speedLift, {y:_point_Y[_currentFloor - 1], ease:Cubic.easeInOut, onComplete:onMoveCom, onCompleteParams:[_currentFloor]});
			}
		}

		/**
		 * 移动完成
		 * @param	currentFloor
		 */
		public function onMoveCom(currentFloor : int) : void {
			mode = "wait";
			// Cc.log("电梯编号："+this.name+"    到达楼层：" + _currentFloor);
			dispatchEvent(new InteractiveEvent(LiftEvent.CHANGE_CURRENT_FLOOR, _currentFloor));
			// 到达指定楼层

			// 离开电梯
			checkGoOutLift();

			dispatchEvent(new InteractiveEvent(LiftEvent.END_OUT_LIFT));
		}

		// 判断另一部电梯状态
		public function checkAction(action : String) : void {
			if (action == "wait") {
				// 另一部电梯非等人状态，则自己进入等人状态
				if (_isGoOut) {
					setTimeout(checkGoInLift, Config.speedInAndOut * 1000);
				} else {
					checkGoInLift();
				}
			} else {
				// 另一部电梯在等人状态，则直接进行下一步
				if (_isGoIn) {
					setTimeout(checkNextStep, Config.speedInAndOut * 1000);
				} else {
					checkNextStep();
				}
			}
		}

		private function checkGoInLift() : void {
			var person : PersonItem;
			var i : int;
			if (_currentFloor == MAX_FLOOR) {
				_moveType = "down";
			}
			if (_currentFloor == MIN_FLOOR) {
				_moveType = "up";
			}
			checkLiftMoveMode();

			_isGoIn = false;
			// 进入电梯
			for (i = 0; i < PersonDataManager.personArr.length; i++) {
				person = PersonDataManager.personArr[i] as PersonItem;
				// 当前楼层等待人要去方向和电梯一致的进入电梯
				// 判断人的方向
				if (person.state == "wait" && person.fromFloor == _currentFloor) {
					// Cc.logch("person", "人要去：" + person.toFloor + "  状态：" + person.state);
					// trace("进入电梯的人来至：" + person.fromFloor);
					if (person.toFloor > _currentFloor) {
						// 向上
						if (_moveType == "up") {
							// 有空位进入
							if (_seatIndex.length > 0) {
								// trace("电梯向上进入电梯")
								goInLift(_currentFloor, person);
								if (person.toFloor > _endFloor) {
									endFloor = person.toFloor;
								}
							}
						} else {
							// 停止状态不管移动方向
							if (_isStop) {
								// 有空位进入
								if (_seatIndex.length > 0) {
									// trace("电梯向上进入电梯")
									goInLift(_currentFloor, person);
									if (person.toFloor > _endFloor) {
										endFloor = person.toFloor;
									}
								}
							}
						}
					} else {
						// 向下
						if (_moveType == "down") {
							// 有空位进入
							if (_seatIndex.length > 0) {
								// trace("电梯向下进入电梯")
								goInLift(_currentFloor, person);
								if (person.toFloor < _endFloor) {
									endFloor = person.toFloor;
								}
							}
						} else {
							// 停止状态不管移动方向
							if (_isStop) {
								// 有空位进入
								if (_seatIndex.length > 0) {
									// trace("电梯向下进入电梯")
									goInLift(_currentFloor, person);
									if (person.toFloor < _endFloor) {
										endFloor = person.toFloor;
									}
								}
							}
						}
					}
				}
			}

			if (_isGoIn) {
				setTimeout(checkNextStep, Config.speedInAndOut * 1000);
			} else {
				checkNextStep();
			}
		}

		private function checkGoOutLift() : void {
			var person : PersonItem;
			var i : int;
			_isGoOut = false;
			for (i = PersonDataManager.personArr.length - 1; i > -1; i--) {
				person = PersonDataManager.personArr[i] as PersonItem;
				// 电梯内部人员在到达指定楼层则出去
				if (person.state == "in" && person.liftIndex == index && person.toFloor == _currentFloor) {
					goOutLift(_currentFloor, person);
				}
			}
		}

		public function checkNextStep() : void {
			var person : PersonItem;
			var i : int;
			var personIn : Boolean;
			// 检查判断电梯下一步动作
			for (i = 0; i < PersonDataManager.personArr.length; i++) {
				person = PersonDataManager.personArr[i] as PersonItem;
				// 电梯有人
				if (person.state == "in" && person.liftIndex == index) {
					// trace("电梯有人")
					personIn = true;
					// 继续向上
					if (person.toFloor > _currentFloor) {
						// trace("电梯向上移动")
						move("up");
						return;
					} else {
						// trace("电梯向下移动")
						move("down");
						return;
					}
				}
			}

			// 电梯没人
			if (!personIn) {
				// trace("电梯没人")
				if (_moveType == "up") {
					// trace("电梯向上没人")
					// 电梯向上没人
					// 响应电梯以上楼层请求
					for (i = 0; i < PersonDataManager.personArr.length; i++) {
						person = PersonDataManager.personArr[i] as PersonItem;
						if (person.state == "wait" && person.fromFloor > currentFloor) {
							// trace("电梯向上移动")
							dispatchEvent(new InteractiveEvent(LiftEvent.CHANGE_TARGET_FLOOR, person.fromFloor));
							move("up");
							return;
						}
					}
					// 响应电梯以下楼层请求
					for (i = 0; i < PersonDataManager.personArr.length; i++) {
						person = PersonDataManager.personArr[i] as PersonItem;
						if (person.state == "wait" && person.fromFloor < currentFloor) {
							// trace("电梯向下移动")
							dispatchEvent(new InteractiveEvent(LiftEvent.CHANGE_TARGET_FLOOR, person.fromFloor));
							move("down");
							return;
						}
					}
				} else {
					// 电梯向下没人
					// trace("电梯向下没人")
					// 响应电梯以下楼层请求
					for (i = 0; i < PersonDataManager.personArr.length; i++) {
						person = PersonDataManager.personArr[i] as PersonItem;
						if (person.state == "wait" && person.fromFloor < currentFloor) {
							// trace("电梯向下移动")
							dispatchEvent(new InteractiveEvent(LiftEvent.CHANGE_TARGET_FLOOR, person.fromFloor));
							move("down");
							return;
						}
					}

					// 响应电梯以上楼层请求
					for (i = 0; i < PersonDataManager.personArr.length; i++) {
						person = PersonDataManager.personArr[i] as PersonItem;
						if (person.state == "wait" && person.fromFloor > currentFloor) {
							// trace("电梯向上移动")
							dispatchEvent(new InteractiveEvent(LiftEvent.CHANGE_TARGET_FLOOR, person.fromFloor));
							move("up");
							return;
						}
					}
				}
				_isStop = true;
			}
			
		}

		// 判断电梯移动模式
		private function checkLiftMoveMode() : void {
			var person : PersonItem;
			var i : int;
			if (_moveType == "up") {
				var upBoo : Boolean;
				for (i = 0; i < PersonDataManager.personArr.length; i++) {
					person = PersonDataManager.personArr[i] as PersonItem;
					// 优先当前楼层人意向
					if (person.fromFloor == _currentFloor && person.toFloor > _currentFloor) {
						upBoo = true;
						break;
					}
					// 当前楼层以上人的意愿
					if (person.fromFloor > _currentFloor && person.toFloor < person.fromFloor) {
						upBoo = true;
						break;
					}
				}
				_moveType = (upBoo) ? ("up") : ("down");
			} else {
				for (i = 0; i < PersonDataManager.personArr.length; i++) {
					person = PersonDataManager.personArr[i] as PersonItem;
					if (person.fromFloor == _currentFloor && person.toFloor < _currentFloor) {
						upBoo = true;
						break;
					}
					if (person.fromFloor < _currentFloor && person.toFloor > person.fromFloor) {
						upBoo = true;
						break;
					}
				}
				_moveType = (upBoo) ? ("down") : ("up");
			}
		}

		/**
		 * 进入电梯
		 * @param	currentFloor
		 */
		private function goInLift(currentFloor : int, person : PersonItem) : void {
			_isGoIn = true;
			var randomNum : int = Rnd.integer(0, _seatIndex.length);
			var randomSeat : int = _seatIndex[randomNum];
			ArrayUtil.removeValueFromArray(_seatIndex, randomSeat);
			var liftPerson : LiftPerson = new LiftPerson();
			liftPerson.update(person);
			this["personBox" + randomSeat].addChild(liftPerson);
			person.seat = randomSeat;
			person.state = "in";
			person.liftIndex = index;
			liftPerson.alpha = 0;
			trace("进入人员from:" + person.fromFloor + "  去向:" + person.toFloor);
			// var parentObj : MovieClip = this.parent;
			// parentObj.onGoInLift(person);
			dispatchEvent(new InteractiveEvent(LiftEvent.GO_IN_LIFT, person));
			TweenLite.to(liftPerson, Config.speedInAndOut, {alpha:1, ease:Bounce.easeIn, onComplete:onGoInLiftCom});
		}

		private function onGoInLiftCom() : void {
			// checkNextStep();
		}

		/**
		 * 离开电梯
		 * @param	currentFloor
		 */
		private function goOutLift(currentFloor : int, person : PersonItem) : void {
			_isGoOut = true;
			removeLiftPerson(person);
			person.state = "out";
			_seatIndex.push(person.seat);
			_seatIndex.sort(Array.NUMERIC);
			deletePeople(person, currentFloor);
			dispatchEvent(new InteractiveEvent(LiftEvent.GO_OUT_LIFT, person));
		}

		private function removeLiftPerson(person : PersonItem) : void {
			for (var i : int = 1; i <= 10; i++) {
				if (this["personBox" + i].numChildren > 0) {
					var liftPerson : LiftPerson = this["personBox" + i].getChildAt(0) as LiftPerson;
					if (liftPerson.fromFloor == person.fromFloor && liftPerson.toFloor == person.toFloor) {
						// trace("移掉" + "来至：" + liftPerson.fromFloor + "  去：" + liftPerson.toFloor);
						TweenLite.to(liftPerson, Config.speedInAndOut, {alpha:0, ease:Bounce.easeIn, onComplete:onGoOutLift, onCompleteParams:[liftPerson]});
					}
				}
			}
		}

		private function onGoOutLift(liftPerson : LiftPerson) : void {
			liftPerson.parent.removeChild(liftPerson);
		}

		/**
		 * 离开电梯
		 */
		private function deletePeople(person : PersonItem, currentFloor : int) : void {
			for (var i : int = PersonDataManager.personArr.length - 1; i > -1; i--) {
				var personItem : PersonItem = PersonDataManager.personArr[i] as PersonItem;
				if (personItem.state == "out") {
					PersonDataManager.deletePerson(i);
					// _personArr.splice(i, 1);
					break;
				}
			}
		}

		public function get seatIndex() : Array {
			return _seatIndex;
		}

		public function set endFloor(value : int) : void {
			_endFloor = value;
			dispatchEvent(new InteractiveEvent(LiftEvent.CHANGE_TARGET_FLOOR, endFloor));
		}

		public function get endFloor() : int {
			return _endFloor;
		}

		public function get currentFloor() : int {
			return _currentFloor;
		}

		public function get mode() : String {
			return _mode;
		}

		public function set mode(mode : String) : void {
			_mode = mode;
		}

		public function get moveType() : String {
			return _moveType;
		}

		public function set moveType(moveType : String) : void {
			_moveType = moveType;
		}

		public function get index() : int {
			return _index;
		}

		public function set index(index : int) : void {
			_index = index;
		}

		public function get isStop() : Boolean {
			return _isStop;
		}
	}
}